#ifndef ORIGINBTC_TRANSACTION_H
#define ORIGINBTC_TRANSACTION_H
#include <iostream>
#include <cstdio>
#include <map>
#include "Uint256.h"
#include "Serialize.h"
#include "Script.h"

class Transaction;


class InPoint {
public:
    InPoint();
    InPoint(Transaction* ptx, unsigned int in);
    void setNull();
    bool isNull();
public:
    Transaction* m_ptx;
    unsigned int m_num;
};

class OutPoint {
public:
    OutPoint();
    OutPoint(Uint256 hashIn, unsigned int in);
    IMPLEMENT_SERIALIZE(READWRITE(FLATDATA(*this));)
    void setNull();
    bool isNull();
    std::string toString() const;
    void print() const;

    friend bool operator<(const OutPoint& a, const OutPoint& b);
    friend bool operator==(const OutPoint& a, const OutPoint& b);
    friend bool operator!=(const OutPoint& a, const OutPoint& b);
public:
    Uint256 m_hash;
    unsigned int m_num;
};

bool operator<(const OutPoint& a, const OutPoint& b) { return a.hash < b.hash || (a.hash == b.hash && a.n < b.n); }
bool operator==(const OutPoint& a, const OutPoint& b) { return a.hash == b.hash && a.n == b.n; }
bool operator!=(const OutPoint& a, const OutPoint& b) { return !(a == b); }

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class TxIn {
public:
    TxIn();
    explicit TxIn(OutPoint prevOutIn, Script scriptSigIn=Script(), unsigned int seq=UINT32_MAX);
    TxIn(Uint256 hashPrevTx, unsigned int outNum, Script scriptSigIn=Script(), unsigned int seq=UINT32_MAX);
    bool isFinal();
    std::string toString()const;
    void print() const;

    bool isMine() const;
    int64_t getDebit() const;

    IMPLEMENT_SERIALIZE
    (
        READWRITE(m_prev_out);
        READWRITE(m_script_sig);
        READWRITE(m_sequence);
    )


    friend bool operator==(const TxIn& a, const TxIn& b);
    friend bool operator!=(const TxIn& a, const TxIn& b);

public:
    OutPoint m_prev_out;
    Script m_script_sig;
    unsigned int m_sequence;
};
bool operator==(const TxIn& a, const TxIn& b) {
    return a.m_prev_out   == b.m_prev_out && a.m_script_sig == b.m_script_sig && a.m_sequence == b.m_sequence
}
bool operator!=(const TxIn& a, const TxIn& b) {
    return !(a == b);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class TxOut {
public:
    TxOut();
    TxOut(int64_t valueIn, Script scriptPubkeyIn);
    void setNull();
    bool isNull();
    Uint256 getHash()const;
    bool isMine();
    int64_t getCredit()const;
    std::string toString()const;
    void print() const;

    friend bool operator==(const TxOut& a, const TxOut& b);
    friend bool operator!=(const TxOut& a, const TxOut& b);


    IMPLEMENT_SERIALIZE
    (
            READWRITE(m_value);
            READWRITE(m_script_pubkey);
    )
public:
    int64_t m_value;
    Script m_script_pubkey;
};

bool operator==(const TxOut& a, const TxOut& b) {
    return a.m_value == b.m_value && a.m_script_pubkey == b.m_script_pubkey;
}
bool operator!=(const TxOut& a, const TxOut& b) {
    return !(a == b);
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class Transaction {

};


#endif //ORIGINBTC_TRANSACTION_H
